﻿using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using Microsoft.AspNetCore.WebUtilities;
using VK.OAuth.Scopes;

namespace VK.OAuth
{
    public class VkOAuth
    {
        protected const string Version = "5.101";

        private const string ParamVersion = "v";
        private const string ParamClientId = "client_id";
        private const string ParamRedirectUri = "redirect_uri";
        private const string ParamGroupIds = "group_ids";
        private const string ParamDisplay = "display";
        private const string ParamScope = "scope";
        private const string ParamResponseType = "response_type";
        private const string ParamState = "state";
        private const string ParamClientSecret = "client_secret";
        private const string ParamCode = "code";
        private const string ParamRevoke = "revoke";

        private const string ResponseKeyError = "error";
        private const string ResponseKeyErrorDescription = "error_description";

        protected const string Host = "https://oauth.vk.com";
        private const string EndpointAuthorize = "/authorize";
        private const string EndpointAccessToken = "/access_token";

        protected const int ConnectionTimeout = 10;
        protected const int HttpStatusCodeOk = 200;

        // private dynamic _httpClient;
        private string _version;
        private string _host;

        public VkOAuth(string version = Version)
        {
            using var a = new HttpClient();
            // _httpClient = new CurlHttpClient(ConnectionTimeout);
            _version = version;
            _host = Host;
        }

        public string GetAuthorizeUrl(string responseType, int clientId, string redirectUri, string display,
            IEnumerable<VkOAuthUserScope> scope = null, string state = null, IEnumerable<int> groupIds = null,
            bool revoke = false)
        {
            var scopeMask = 0;
            if (scope != null)
                foreach (var scopeSetting in scope)
                {
                    scopeMask |= (int)scopeSetting;
                }

            var @params = new Dictionary<string, string>()
            {
                { ParamClientId, clientId.ToString() },
                { ParamRedirectUri, redirectUri },
                { ParamDisplay, display },
                { ParamScope, scopeMask.ToString() },
                { ParamState, state },
                { ParamResponseType, responseType },
                { ParamVersion, _version },
            };

            if (groupIds is not null && groupIds.Any())
            {
                @params[ParamGroupIds] = string.Join(',', groupIds);
            }

            if (revoke)
            {
                @params[ParamRevoke] = "1";
            }

            return QueryHelpers.AddQueryString(_host + EndpointAuthorize, @params);
        }
    }
}